# CPA / CLI Proxy API details learned from original extension Source repository checked: ```text https://github.com/QLHazyCoder/codex-oauth-automation-extension commit d058676f9579825f74a02e9d8264868eb7d7e896 ``` Relevant source files: ```text background/panel-bridge.js tests/background-panel-bridge-module.test.js background/steps/platform-verify.js tests/background-platform-verify-cpa-api.test.js ``` ## Management origin The extension does **not** use the full `CPA_VPS_URL` path as the API base. It derives the origin: ```js const origin = new URL(CPA_VPS_URL).origin; ``` Example: ```text CPA_VPS_URL=http://192.168.2.62:8317/management.html origin=http://192.168.2.62:8317 ``` ## Auth headers For CPA management API calls, the original extension sends both headers: ```text Authorization: Bearer [CPA_VPS_PASSWORD] X-Management-Key: [CPA_VPS_PASSWORD] Accept: application/json Content-Type: application/json ``` During the successful Hermes run, `Authorization: Bearer ...` alone worked, but the reusable workflow should include both headers to match the extension and tests. ## Generate Codex OAuth URL Original extension endpoint: ```text GET /v0/management/codex-auth-url ``` The CPA management UI also calls: ```text GET /v0/management/codex-auth-url?is_webui=true ``` Both shapes are valid enough to try. Prefer the original extension endpoint first; if the UI is already open or remote-browser mode is expected, `?is_webui=true` is acceptable. The extension extracts the OAuth URL from any of: ```text url auth_url authUrl data.url data.auth_url data.authUrl ``` It extracts the OAuth state from any of: ```text state auth_state authState data.state data.auth_state data.authState ``` If the API payload has no explicit state, parse `state` from the returned OAuth URL. ## Submit localhost callback Before submission, validate: ```text callback URL parses as URL callback query has code callback query has state if expected cpaOAuthState is known, it must equal callback.state ``` Endpoint: ```text POST /v0/management/oauth-callback ``` Body: ```json { "provider": "codex", "redirect_url": "http://localhost:1455/auth/callback?code=[REDACTED]&state=[REDACTED]" } ``` Success can be: ```json {"status":"ok"} ``` or a message field such as: ```json {"message":"CPA API 回调提交成功"} ``` ## Verify Status: ```text GET /v0/management/get-auth-status?state= ``` Expected: ```json {"status":"ok"} ``` Auth files: ```text GET /v0/management/auth-files ``` Look for a Codex file such as: ```json { "provider": "codex", "status": "active", "account_type": "oauth", "name": "codex--free.json" } ``` ## Pitfalls - Do not call root `/codex-auth-url`; it returns 404. - Do not call root `/api/auth/url` for Codex. On the tested CPA instance it returned `amp upstream proxy not available`, which is unrelated to Codex OAuth. - Do not submit a callback if its `state` does not match the generated CPA OAuth state; original extension fails fast before any API call. - If `CPA_VPS_PASSWORD` is empty, stop before API calls; original extension requires the management key. - If direct API discovery fails, open `management.html`, log in, click “OAuth 登录 → 开始 Codex 登录”, and inspect requests. The UI network calls reveal `/v0/management/codex-auth-url?is_webui=true` and polling `/v0/management/get-auth-status`.