feat: add codex-oauth provider support for ChatGPT-authenticated Code…#87
feat: add codex-oauth provider support for ChatGPT-authenticated Code…#87kikuchy wants to merge 1 commit into
Conversation
tak848
left a comment
There was a problem hiding this comment.
Thanks for putting this together -- really nice to see a ChatGPT-plan path land on ccgate!
A handful of questions and small suggestions inline, all non-blocking. The biggest one is around project AGENTS.md potentially flowing into the classifier prompt; the rest are docs / comment polish and one latency open question. Happy to revisit any of them -- feel free to push back where you read it differently!
| // Keep the managed ccgate CODEX_HOME self-contained. The file | ||
| // contains no secret, but mode 0600 matches the adjacent auth.json | ||
| // sensitivity and avoids leaking user configuration details. | ||
| if err := os.WriteFile(configPath, []byte("cli_auth_credentials_store = \"file\"\n"), 0o600); err != nil { |
There was a problem hiding this comment.
Probably the most interesting finding from my read! The managed config.toml only sets cli_auth_credentials_store = "file", with project_doc_max_bytes left at the Codex default (32 KiB). So Codex's agents_md.rs walks from the PermissionRequest cwd up to the project root and concatenates every AGENTS.md it finds into the first-turn instructions. The sandbox guards side effects (approvalPolicy=never, sandbox=read-only, networkAccess=false), but it does not guard against project-side prompts biasing the classifier verdict.
Would you consider appending project_doc_max_bytes = 0 to this initial template? In openai/codex codex-rs/core/src/agents_md.rs, both read_agents_md and agents_md_paths short-circuit when max_total == 0, so it is a clean disable, not a truncate.
Existing managed homes will not be re-written because the os.Stat check above already returns — totally fine, no migration needed. Users who already initialised the default home can edit the file manually (or delete it and let ccgate regenerate; auth.json is not touched).
| // Keep the managed ccgate CODEX_HOME self-contained. The file | ||
| // contains no secret, but mode 0600 matches the adjacent auth.json | ||
| // sensitivity and avoids leaking user configuration details. | ||
| if err := os.WriteFile(configPath, []byte("cli_auth_credentials_store = \"file\"\n"), 0o600); err != nil { |
There was a problem hiding this comment.
Curious about this choice! Why pin file over keyring / auto? Would love a one-line note here so future readers do not switch it back. Best guess: keyring shares one OS service name with the user's regular ~/.codex login and would collide.
| } | ||
| } | ||
|
|
||
| s, err := startAppServer(ctx, c.CodexBin, c.CodexHome) |
There was a problem hiding this comment.
Open question on latency, not a blocker! Each Decide spawns a fresh app-server (initialize → account/read → thread/start → turn/start → wait turn/completed → kill). That is noticeably heavier than the other providers' single HTTP roundtrip. Would it be possible to include a metrics.jsonl excerpt (latency_ms) from a real session in the PR description so users can compare against anthropic / openai?
Two small adjacent levers worth noting:
turn/startdoes not pass a reasoning effort hint. If the Codex protocol accepts a low / minimal effort hint for classification, that could cut latency on reasoning-tier models.docs/providers.mdleaves the default model as "set explicitly". A documented recommended model for classification (mini-tier if available under the ChatGPT plan) would help users avoid landing on the most expensive option by accident.
| CODEX_HOME="${XDG_STATE_HOME:-$HOME/.local/state}/ccgate/codex-oauth/codex-home" codex login | ||
| ``` | ||
|
|
||
| Set `provider.codex_home` if you intentionally want to reuse another Codex profile, such as `~/.codex`. Set `provider.codex_bin` if `codex` is not on `PATH`. The child app-server process has `CODEX_API_KEY`, `OPENAI_API_KEY`, and `CCGATE_OPENAI_API_KEY` removed from its environment so this provider does not silently fall back to API-key billing. |
There was a problem hiding this comment.
Two caveats that might be worth surfacing here for users who set provider.codex_home themselves (especially when pointing at ~/.codex):
- The managed default home gets
cli_auth_credentials_store = "file"written automatically, but a self-managed home does not. Worth mentioning so users do not assume ccgate set it for them. - Codex auto-loads
AGENTS.mdfrom bothCODEX_HOME/AGENTS{,.override}.md(global) and fromcwdup to the project root (project), concatenating them into first-turn instructions. To keep classification verdicts independent of whatever the user is running Codex / Claude Code for, recommend settingproject_doc_max_bytes = 0in the Codexconfig.toml, and avoidingAGENTS.mdinside the CODEX_HOME being pointed at.
The second point also applies to the managed home (pairs with the suggestion on the client.go config template).
| CODEX_HOME="${XDG_STATE_HOME:-$HOME/.local/state}/ccgate/codex-oauth/codex-home" codex login | ||
| ``` | ||
|
|
||
| 普段使いの `~/.codex` などを意図的に再利用したい場合は `provider.codex_home`、`codex` が `PATH` にない場合は `provider.codex_bin` を設定します。`codex-oauth` の子プロセスからは `CODEX_API_KEY` / `OPENAI_API_KEY` / `CCGATE_OPENAI_API_KEY` を除去するため、API key 課金へ silent に落ちることはありません。 |
There was a problem hiding this comment.
Same caveat as on docs/providers.md:48 — could you mirror it here as well?
- Managed default home gets
cli_auth_credentials_store = "file"auto-written; self-managedcodex_homedoes not — worth surfacing. - Codex loads
AGENTS.mdfromCODEX_HOME/AGENTS{,.override}.md(global) and fromcwdup to repo root (project), concatenating them into first-turn instructions. Recommendproject_doc_max_bytes = 0in the Codexconfig.tomlto keep classification verdicts independent of the user's normal Codex / Claude Code workflow context.
| // Alternatives: | ||
| // name: 'openai', model: 'gpt-4o-mini', (env: OPENAI_API_KEY) | ||
| // name: 'gemini', model: 'gemini-2.0-flash', (env: GEMINI_API_KEY) | ||
| // name: 'codex-oauth', model: 'gpt-5.4', (ChatGPT OAuth via Codex app-server) |
There was a problem hiding this comment.
Small suggestion! Could the example here use a mini-tier model? Classification needs deterministic structured output, not reasoning, so the cheapest model that supports outputSchema is likely the right default. Worth recommending the same in docs/providers.md too (currently "set explicitly").
Why
Currently, ccgate requires explicit API keys for LLM providers. However, users who already have a ChatGPT subscription may prefer to use the Codex CLI's built-in OAuth authentication instead of provisioning and paying for a separate OpenAI developer API key. This change allows users to run ccgate using their existing ChatGPT subscription by leveraging the native Codex CLI session.
What
codex-oauthLLM provider.codex_binandcodex_homeconfiguration options to securely manage the Codex CLI execution environment without leaking existing environment variables.claude.schema.jsonandcodex.schema.json) to support the new provider configurations.(Also we can communicate with Japanese.)