openai-codex-oauth 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 RespectMathias
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/NOTICE ADDED
@@ -0,0 +1,27 @@
1
+ This package contains OAuth and Codex integration logic originally informed by
2
+ the OpenCode project.
3
+
4
+ OpenCode
5
+ Repository: https://github.com/anomalyco/opencode
6
+
7
+ MIT License
8
+
9
+ Copyright (c) 2025 opencode
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # openai-codex-oauth
2
+
3
+ OpenAI Codex OAuth provider and token helpers for the Vercel AI SDK.
4
+
5
+ This package lets local apps use a user's OpenAI Codex OAuth session with AI SDK functions such as `generateText` and `streamText`. It is intended for personal/local applications that already own the user's token storage boundary.
6
+
7
+ It is unofficial and is not affiliated with, endorsed by, or sponsored by OpenAI.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install openai-codex-oauth ai @ai-sdk/openai @ai-sdk/provider
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```ts
18
+ import { generateText } from 'ai';
19
+ import { createOpenAIOAuth } from 'openai-codex-oauth';
20
+
21
+ const openai = createOpenAIOAuth({
22
+ tokens: {
23
+ accessToken: process.env.OPENAI_OAUTH_ACCESS_TOKEN!,
24
+ refreshToken: process.env.OPENAI_OAUTH_REFRESH_TOKEN!,
25
+ accountId: process.env.OPENAI_OAUTH_ACCOUNT_ID!,
26
+ },
27
+ });
28
+
29
+ const result = await generateText({
30
+ model: openai('gpt-5.3-codex'),
31
+ prompt: 'Reply with exactly: hello',
32
+ });
33
+
34
+ console.log(result.text);
35
+ ```
36
+
37
+ ## Sign In With Device OAuth
38
+
39
+ ```ts
40
+ import { startOpenAIDeviceFlow } from 'openai-codex-oauth';
41
+
42
+ const flow = await startOpenAIDeviceFlow();
43
+
44
+ console.log(`Open ${flow.url}`);
45
+ console.log(`Enter code ${flow.code}`);
46
+
47
+ const tokens = await flow.complete();
48
+ ```
49
+
50
+ `flow.complete()` polls until the user authorizes the code, exchanges the authorization grant for OAuth tokens, and returns:
51
+
52
+ ```ts
53
+ type OpenAIOAuthTokens = {
54
+ accessToken: string;
55
+ refreshToken?: string;
56
+ expiresAt?: number;
57
+ idToken?: string;
58
+ accountId?: string;
59
+ };
60
+ ```
61
+
62
+ Persist these tokens in secure storage. They are account credentials.
63
+
64
+ ## Token Store
65
+
66
+ For real apps, prefer a `TokenStore` over hard-coded env values. The provider loads tokens lazily, refreshes them when they are near expiry, then saves refreshed tokens back through the same store.
67
+
68
+ ```ts
69
+ import { createOpenAIOAuth, type TokenStore } from 'openai-codex-oauth';
70
+
71
+ const tokenStore: TokenStore = {
72
+ async load() {
73
+ const raw = await secureStore.get('openai-codex-oauth');
74
+ return raw ? JSON.parse(raw) : undefined;
75
+ },
76
+ async save(tokens) {
77
+ await secureStore.set('openai-codex-oauth', JSON.stringify(tokens));
78
+ },
79
+ };
80
+
81
+ const openai = createOpenAIOAuth({ tokenStore });
82
+ ```
83
+
84
+ ## Local Codex Auth File
85
+
86
+ For Node apps that already have Codex auth from `codex login` or `npx @openai/codex login`:
87
+
88
+ ```ts
89
+ import { createOpenAIOAuth } from 'openai-codex-oauth';
90
+ import { createCodexAuthFileStore } from 'openai-codex-oauth/node';
91
+
92
+ const openai = createOpenAIOAuth({
93
+ tokenStore: createCodexAuthFileStore(),
94
+ });
95
+ ```
96
+
97
+ The Node helper searches:
98
+
99
+ - `$CHATGPT_LOCAL_HOME/auth.json`
100
+ - `$CODEX_HOME/auth.json`
101
+ - `~/.chatgpt-local/auth.json`
102
+ - `~/.codex/auth.json`
103
+
104
+ When refreshed tokens are written, the helper writes the auth file with mode `0600` where supported by the OS.
105
+
106
+ ## Streaming
107
+
108
+ ```ts
109
+ import { streamText } from 'ai';
110
+ import { createOpenAIOAuth } from 'openai-codex-oauth';
111
+
112
+ const openai = createOpenAIOAuth({ tokenStore });
113
+
114
+ const result = streamText({
115
+ model: openai('gpt-5.4'),
116
+ prompt: 'Write one sentence about the moon.',
117
+ });
118
+
119
+ for await (const delta of result.textStream) {
120
+ process.stdout.write(delta);
121
+ }
122
+ ```
123
+
124
+ ## Browser/Web Proxy Handler
125
+
126
+ Browsers should not call the ChatGPT Codex backend directly because those requests can fail CORS and expose account tokens to cross-origin infrastructure. In browser runtimes, `createCodexOAuthFetch` automatically routes Codex API calls through `/api/proxy/openai/codex` unless `browserProxyBaseUrl: false` is set.
127
+
128
+ Create a server/API route with the framework-agnostic proxy helper:
129
+
130
+ ```ts
131
+ import { createOpenAIOAuthProxy } from 'openai-codex-oauth/proxy';
132
+
133
+ const proxy = createOpenAIOAuthProxy();
134
+
135
+ export const responses = proxy.responses;
136
+ ```
137
+
138
+ The proxy expects browser requests to send `Authorization: Bearer <token>` and `ChatGPT-Account-Id`. It forwards to the Codex backend server-side and returns `Cache-Control: no-store` responses.
139
+
140
+ ## Credential Safety
141
+
142
+ OAuth tokens are password-equivalent for the connected OpenAI account.
143
+
144
+ - Do store tokens in OS keychain storage, encrypted app storage, or a trusted server-side secret store.
145
+ - Do not store tokens in browser `localStorage`, plaintext app config, Git, logs, analytics, crash reports, or build output.
146
+ - Do not expose this provider from a shared hosted API unless each user has isolated storage and authorization.
147
+ - Do not pool, proxy, or redistribute tokens across users.
148
+ - Use `tokenStore` in production so refreshes are persisted and stale access tokens are replaced.
149
+ - Pass `tokens` directly only for short-lived scripts, tests, or already-secured server runtime secrets.
150
+
151
+ The package does not phone home, does not persist tokens unless you provide a `TokenStore`, and does not log tokens. The Node auth-file helper writes refreshed tokens only to the local Codex auth file it loaded or the explicit path you pass.
152
+
153
+ ## API
154
+
155
+ ### `createOpenAIOAuth(settings)`
156
+
157
+ Creates an AI SDK provider. The provider is callable:
158
+
159
+ ```ts
160
+ const model = openai('gpt-5.3-codex');
161
+ ```
162
+
163
+ Important settings:
164
+
165
+ - `tokens`: in-memory OAuth credentials for scripts/tests.
166
+ - `tokenStore`: async credential store used for loading and saving refreshed tokens.
167
+ - `fetch`: custom fetch implementation.
168
+ - `baseURL`: Codex upstream base URL. Defaults to `https://chatgpt.com/backend-api/codex`.
169
+ - `browserProxyBaseUrl`: browser proxy base URL. Defaults to `/api/proxy/openai/codex`; pass `false` to disable browser proxy routing.
170
+ - `clientId`, `issuer`, `tokenUrl`: OAuth endpoint overrides.
171
+ - `headers`: additional upstream headers.
172
+ - `instructions`: default `instructions` field for `/responses` bodies.
173
+ - `store`: default OpenAI Responses `store` value. Defaults to `false`.
174
+ - `originator`: upstream `originator` header. Pass `false` to omit.
175
+ - `onTokens`: callback invoked after a successful refresh.
176
+
177
+ ### `startOpenAIDeviceFlow(options)`
178
+
179
+ Starts OpenAI's Codex device flow at `https://auth.openai.com/codex/device` and returns `{ url, code, instructions, complete }`.
180
+
181
+ ### `createCodexOAuthFetch(settings)`
182
+
183
+ Creates a `fetch` implementation that rewrites AI SDK `/v1/responses` requests to the Codex backend and injects OAuth headers.
184
+
185
+ In browsers, it routes through `browserProxyBaseUrl` by default to avoid direct Codex CORS failures.
186
+
187
+ ### `createOpenAIOAuthProxy(options)`
188
+
189
+ Creates framework-agnostic server handlers for browser-safe Codex API proxying. Import from `openai-codex-oauth/proxy`.
190
+
191
+ ### `createCodexAuthFileStore(options)`
192
+
193
+ Node-only helper exported from `openai-codex-oauth/node`. Loads and saves Codex-compatible `auth.json` token files.
194
+
195
+ ## Behavior
196
+
197
+ - Uses OpenAI's device authorization endpoints for Codex OAuth.
198
+ - Derives `accountId` from the JWT claim `https://api.openai.com/auth.chatgpt_account_id` when available.
199
+ - Requires `accountId` before making Codex requests.
200
+ - Refreshes tokens before expiry when a `refreshToken` is available.
201
+ - Sends requests to `https://chatgpt.com/backend-api/codex/responses` by default.
202
+ - Injects `Authorization`, `ChatGPT-Account-Id`, `OpenAI-Beta`, and `originator` headers.
203
+ - Normalizes Responses payloads by defaulting `store` to `false` and removing `max_output_tokens` for Codex compatibility.
204
+ - Implements non-streaming generation by collecting stream output because the Codex endpoint is stream-first.
205
+
206
+ ## Attribution
207
+
208
+ Some OAuth/Codex integration behavior was originally informed by OpenCode. See `NOTICE`.
209
+
210
+ ## Limitations
211
+
212
+ - This is an unofficial integration over Codex/ChatGPT backend behavior, which can change.
213
+ - Embedding and image model factories intentionally throw `NoSuchModelError` for now.
214
+ - The package does not provide a multi-user auth service. You own user isolation and secure storage.