Connect GoClaw to ChatGPT via OAuth — no API key needed, uses your existing OpenAI account.
GoClaw supports OAuth 2.0 PKCE authentication for the OpenAI/Codex provider. This lets you use ChatGPT (the openai-codex provider) without a paid API key by authenticating through your OpenAI account via browser. Tokens are stored securely in the database and refreshed automatically before expiry.
This flow is distinct from standard API key providers — it is only needed if you want to use the openai-codex provider type.
GoClaw supports routing OAuth tokens to multiple provider types beyond OpenAI/Codex. In v3, the provider type media covers services like Suno (AI music) and DashScope (Alibaba media generation) that use OAuth or session tokens rather than plain API keys.
| Provider type | Services | Auth method |
|---|---|---|
openai-codex |
ChatGPT via Responses API | OAuth 2.0 PKCE |
suno |
Suno AI music generation | Session token |
dashscope |
Alibaba DashScope (when OAuth-based) | OAuth or API key |
Media provider types are registered in the llm_providers table with the appropriate provider_type value. The gateway resolves the correct token source and refresh logic based on provider_type at request time.
flowchart TD
UI["Web UI: click Connect ChatGPT"] --> START["POST /v1/auth/openai/start"]
START --> PKCE["Gateway generates\nPKCE verifier + challenge"]
PKCE --> SERVER["Callback server starts\non port 1455"]
SERVER --> URL["Auth URL returned to UI"]
URL --> BROWSER["User opens browser\n→ auth.openai.com"]
BROWSER --> LOGIN["User logs in to OpenAI"]
LOGIN --> CB["Browser redirects to\nlocalhost:1455/auth/callback"]
CB --> EXCHANGE["Code exchanged for tokens\nat auth.openai.com/oauth/token"]
EXCHANGE --> SAVE["Access token → llm_providers\nRefresh token → config_secrets"]
SAVE --> READY["openai-codex provider\nregistered and ready"]
The gateway starts a temporary HTTP server on port 1455 to receive the OAuth callback. This port must be reachable from the browser (i.e. accessible on localhost when using the web UI locally, or via port forwarding for remote servers).
- Open the GoClaw web dashboard
- Navigate to Providers → ChatGPT OAuth
- Click Connect — the gateway calls
POST /v1/auth/openai/startand returns an auth URL - Your browser opens
auth.openai.com— log in and approve access - The callback lands on
localhost:1455/auth/callback— tokens are saved automatically
If the browser callback can't reach port 1455 on the server, use the manual redirect URL fallback:
- Start the flow via web UI — copy the auth URL
- Open the auth URL in your local browser
- After approving, your browser tries to redirect to
localhost:1455/auth/callbackand fails (since the server is remote) - Copy the full redirect URL from the browser address bar (it starts with
http://localhost:1455/auth/callback?code=...) - Paste it into the web UI's manual callback field — the UI calls
POST /v1/auth/openai/callbackwith the URL - The gateway extracts the code, completes the exchange, and saves the tokens
The ./goclaw auth subcommand talks to the running gateway to check and manage OAuth state.
./goclaw auth statusOutput when authenticated:
OpenAI OAuth: active (provider: openai-codex)
Use model prefix 'openai-codex/' in agent config (e.g. openai-codex/gpt-4o).
Output when not authenticated:
No OAuth tokens found.
Use the web UI to authenticate with ChatGPT OAuth.
The command hits GET /v1/auth/openai/status on the running gateway. The gateway URL is resolved from environment variables:
| Variable | Default |
|---|---|
GOCLAW_GATEWAY_URL |
— (overrides host+port) |
GOCLAW_HOST |
127.0.0.1 |
GOCLAW_PORT |
3577 |
Set GOCLAW_TOKEN to authenticate the CLI request if the gateway requires a token.
./goclaw auth logout
# or explicitly:
./goclaw auth logout openaiThis calls POST /v1/auth/openai/logout, which:
- Deletes the
openai-codexprovider row fromllm_providers - Deletes the refresh token from
config_secrets - Unregisters the
openai-codexprovider from the in-memory registry
All endpoints require Authorization: Bearer <GOCLAW_TOKEN>.
| Method | Path | Description |
|---|---|---|
GET |
/v1/auth/openai/status |
Check if OAuth is active and token is valid — returns { authenticated, provider_name? } |
POST |
/v1/auth/openai/start |
Start OAuth flow — returns { auth_url } or { status: "already_authenticated" } |
POST |
/v1/auth/openai/callback |
Submit redirect URL for manual exchange — body: { redirect_url } — returns { authenticated, provider_name, provider_id } |
POST |
/v1/auth/openai/logout |
Remove stored tokens and unregister provider — returns { status: "logged out" } |
GoClaw stores OAuth tokens across two tables:
| Storage | What is stored |
|---|---|
llm_providers |
Access token (as api_key), expiry timestamp in settings JSONB |
config_secrets |
Refresh token under key oauth.openai-codex.refresh_token |
The DBTokenSource handles the full lifecycle:
- Cache: the access token is cached in memory and reused until within 5 minutes of expiry
- Auto-refresh: when the token is about to expire, the refresh token is retrieved from
config_secretsand a new token is fetched fromauth.openai.com/oauth/token - Persistence: both the new access token (in
llm_providers) and new refresh token (inconfig_secrets) are written back to the database after refresh - Graceful degradation: if refresh fails but a token still exists, the existing token is returned and a warning is logged — the provider stays usable until the token actually expires
The OAuth scopes requested during login are:
openid profile email offline_access api.connectors.read api.connectors.invoke
offline_access is what grants the refresh token for long-lived sessions.
Once authenticated, reference the provider with the openai-codex/ prefix:
{
"agent": {
"key": "my-agent",
"provider": "openai-codex/gpt-4o"
}
}The openai-codex provider name is fixed — it matches the DefaultProviderName constant in the oauth package.
Check status after onboarding:
source .env.local
./goclaw auth statusForce re-authentication (logout then reconnect via UI):
./goclaw auth logout
# then open web UI → Providers → Connect ChatGPT| Issue | Cause | Fix |
|---|---|---|
cannot reach gateway at http://127.0.0.1:3577 |
Gateway not running | Start gateway first: ./goclaw |
failed to start OAuth flow (is port 1455 available?) |
Port 1455 in use | Stop whatever is using port 1455 |
| Callback fails on remote server | Browser can't reach server port 1455 | Use the manual redirect URL flow (paste URL into web UI) |
token invalid or expired from status endpoint |
Refresh failed | Run ./goclaw auth logout then re-authenticate |
unknown provider: xyz from logout |
Unsupported provider name | Only openai is supported: ./goclaw auth logout openai |
| Agent gets 401 from ChatGPT | Token expired and refresh failed | Re-authenticate via web UI |
- Providers Overview — all supported LLM providers and how to configure them
- Hooks & Quality Gates — add validation to agent outputs