Codex-Auth is a Python package that provides an OpenAI-compatible API proxy. Its shipped providers support authenticated ChatGPT Web and Microsoft 365 Copilot Chat sessions behind one namespaced model catalog. It uses direct HTTP, SSE, and WebSocket transports, so Chromium and Playwright are not required at runtime.
ChatGPT's web endpoints are undocumented and can change without notice. A ChatGPT subscription is not an OpenAI API subscription.
- β¨ Features
- π Getting Started
- π» Usage
- βοΈ Deploy on Render
- πΈ Screenshots
- π Connecting Tools
- ποΈ Architecture
- π License
- πͺ Cookie Authentication: Loads a Netscape-format ChatGPT
cookies.txt. - π OpenAI Compatible: Supports
/v1/chat/completionsand/v1/models. - πͺΆ Low Memory: No browser process, renderer, DOM, or JavaScript heap.
- β‘ Streaming Core: Reconstructs assistant text from ChatGPT SSE events.
- π Dashboard: Browser login protects runtime logs, usage, and model status.
- π Session Refresh: Validates and activates pasted or uploaded
cookies.txtexports without restarting the service. - π¦ CLI Tool: Includes the
codex-authCLI built with Typer and Rich.
HTTP-only mode supports text and canonical streaming without launching Chromium. Attachment and web-search availability depends on the authenticated ChatGPT account and upstream permissions. Generic function tools, Canvas, and image-generation responses are not yet exposed by the proxy.
pipx install codex-auth-proxy
codex-auth installThe install command confirms that no browser download is needed.
git clone https://github.com/yutuknown/codex-auth.git
cd codex-auth
python -m pip install -e .Export your signed-in chatgpt.com cookies in Netscape HTTP Cookie File format
and save them at:
.codex/cookies.txt
The .codex directory is ignored by Git. Never commit or share this file.
Alternatively, set CODEX_AUTH_COOKIE_FILE to a different path.
For Microsoft 365 Copilot, save the Netscape cookie export at
.codex/m365-cookies.txt and the current Copilot connection metadata at
.codex/m365-auth.json. A captured OAuth refresh exchange can be stored at
.codex/m365-oauth.json, then select a namespaced model such as
m365-copilot:auto or m365-copilot:gpt-5.5-think-deeper. Render deployments
can provide the same values through
CODEX_AUTH_M365_COOKIES, CODEX_AUTH_M365_AUTH_JSON, and
CODEX_AUTH_M365_OAUTH_JSON.
The Account dashboard is provider-first: it exposes separate connection,
model, credential-health, and account views for each registered provider.
Microsoft 365 profile data is optional and read-only. Configure
CODEX_AUTH_M365_GRAPH_JSON for a Graph User.Read access token and, when a
durable refresh flow is available, CODEX_AUTH_M365_GRAPH_OAUTH_JSON. A
missing or expired Graph profile token never prevents Microsoft 365 chat
generation.
The provider discovers the current account-visible Microsoft model selector
from authenticated GET https://m365.cloud.microsoft/chat hydration data. The
result is cached for 15 minutes and safely falls back to the last known catalog
if a refresh fails. Use GET /v1/models?refresh=true or
GET /api/providers/m365-copilot/models?refresh=true to force a refresh.
The Microsoft 365 web cookies validate the signed-in web shell, but they do not
contain the OAuth refresh token used by the site. The bearer in
m365-auth.json is short-lived. When m365-oauth.json is present, the adapter
uses the captured grant_type=refresh_token exchange before expiry, rotates
both returned tokens atomically, and keeps the browser-free runtime renewable.
Without it, the adapter reports generation_ready: false after the bearer
expires instead of pretending a cookie-only session can generate.
codex-auth start --port 8000The OpenAI-compatible base URL is http://127.0.0.1:8000/v1.
curl http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5-3","messages":[{"role":"user","content":"Reply with OK"}]}'When CODEX_AUTH_API_KEY is configured, also send:
Authorization: Bearer <CODEX_AUTH_API_KEY>
Visit /login, enter CODEX_AUTH_API_KEY, and the server creates a secure
HttpOnly dashboard session. The raw key is not stored in the browser cookie.
The Account page can replace an expired session by pasting a Netscape cookie
export or selecting cookies.txt. The server validates the replacement against
the account endpoints before atomically activating it. Cookie values are not
returned by the API or included in request traces.
For the one active personal Microsoft 365 account, the selected Microsoft 365
provider card also has a separate Generation credentials control. Import
the existing m365-auth.json record and m365-oauth.json refresh-exchange
record together. It reports only lifecycle metadata (active, expiring soon,
refreshing, refresh failed, or re-import required), never token values.
You can refresh the running service immediately or explicitly clear its local
runtime copy. On Render, dashboard imports and rotated credentials are
temporary: update both CODEX_AUTH_M365_AUTH_JSON and
CODEX_AUTH_M365_OAUTH_JSON secrets to survive a restart or deploy.
beta/ contains a deliberately isolated, cookie-free M365 SignalR experiment.
It is not part of the production registry or Render deployment. Create fresh
local beta/ms365-auth.json and beta/ms365-route.json files from the
redacted examples, including the route identity and OAuth request metadata
captured from one authenticated M365 chat connection. Check only safe readiness
state with:
python -m codex_auth.beta.m365_bearer statusThe live proof is intentionally opt-in and sends one harmless text prompt:
$env:CODEX_AUTH_M365_BETA_CONFIRM = "1"
python -m codex_auth.beta.m365_bearer probeThe beta never loads cookies and must not be treated as production-ready unless the probe completes successfully with zero cookies.
The included Dockerfile has no browser dependencies, and render.yaml uses
Render's Free plan.
- Create a Render Blueprint or Docker web service from this repository.
- Set
CODEX_AUTH_COOKIESto the complete Netscape cookie-file contents. - If Render cannot perform the cookie-to-token exchange, set
CODEX_AUTH_ACCESS_TOKENfrom the same authenticated browser session. - Generate a private
CODEX_AUTH_API_KEY. - Replace the cookies and access token when the ChatGPT session expires.
The health check is GET /healthz. Secrets must remain in Render environment
variables and must never be committed.
Dashboard cookie replacement takes effect immediately and writes the configured
cookie file. Render's default filesystem is ephemeral, so also update the
CODEX_AUTH_COOKIES environment secretβor attach a persistent diskβif the new
cookies must survive a restart or redeploy.
See docs/low-memory-architecture.md for the
request algorithm and memory characteristics.
| Authentication Setup | API Server Logs | CLI Chat Interface |
|---|---|---|
![]() |
![]() |
![]() |
Configure any OpenAI-compatible client with:
- Base URL:
http://127.0.0.1:8000/v1or your Render URL followed by/v1 - API Key:
CODEX_AUTH_API_KEY - Model: A slug returned by
GET /v1/models
graph LR
A[AI Tool / IDE] -->|OpenAI API Request| B(FastAPI Server)
B --> R{Provider registry}
R -->|default or openai-web:model| C[ChatGPT web adapter]
R -->|m365-copilot:auto| M[Microsoft 365 web adapter]
C -->|Provider-local admission lock| D[ChatGPT conversation]
M -->|Provider-local admission lock| H[Copilot SignalR chat hub]
D --> E[SSE and canonical reconciler]
H --> A
E --> A
- FastAPI handles API routing, API-key checks, and the dashboard.
- The provider registry selects an isolated adapter without initializing unrelated providers.
- curl-cffi maintains the authenticated HTTP cookie session.
- The response reconciler combines SSE delivery with the canonical stored assistant message for reliable long multimodal and web-search responses.
- Typer and Rich power the CLI.
Provider selection is backward compatible: an unqualified model such as auto
uses the default provider. Multi-provider clients can use a namespaced model
such as openai-web:auto or send the optional provider field. Microsoft 365
Copilot text and web-search generation are implemented through its web
SignalR transport; file input is rejected explicitly until its upload protocol
is implemented. Gemini is intentionally not registered in the shipped runtime
yet. See
the provider architecture and implementation roadmap.
Microsoft 365 model IDs are discovered dynamically and map to the tone field
in the SignalR chat invocation. At the time of the latest verified session:
| API model | Captured Microsoft tone |
|---|---|
m365-copilot:auto |
Magic |
m365-copilot:quick-response |
Chat |
m365-copilot:think-deeper |
Reasoning |
m365-copilot:gpt-5.5-quick-response |
Gpt_5_5_Chat |
m365-copilot:gpt-5.5-think-deeper |
Gpt_5_5_Reasoning |
- @yutuknown - Creator & Lead Developer
- Antigravity AI - AI Pair Programmer
Distributed under the MIT License. See LICENSE for more information.


